﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLocalServer>
#include <QLocalSocket>
#include <QDataStream>
#include <QDebug>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QThread>
#include <QMutex>
#include <QQueue>
#include <QMessageBox>
#include <QTimer>
#include <QDateTime>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , dataProcessor(new DataProcessor(this))
    , m_server(new QLocalServer(this))
    , m_client(nullptr)
    , m_dataStream(nullptr)
    , sendTimer(new QTimer(this))
    , settings(new QSettings("config.ini", QSettings::IniFormat))
    , dataCount(0)
    , queryCount(0)
    , sentCount(0)
    , serverRunning(false)
    , isSending(false)
    , isPaused(false)
    , retryCount(0)
{
    ui->setupUi(this);
    setWindowTitle(QString::fromLocal8Bit("巢目外接调试"));
    
    // 初始化数据库
    initDatabase();
    
    // 启动数据处理线程
    dataProcessor->start();
    
    // 连接信号
    connect(dataProcessor, &DataProcessor::dataProcessed, this, &MainWindow::updateCounter);
    connect(sendTimer, &QTimer::timeout, this, &MainWindow::sendNextData);
    
    // 设置默认时间范围（今天）
    QDateTime now = QDateTime::currentDateTime();
    ui->startTimeEdit->setDateTime(now.addDays(-1));
    ui->endTimeEdit->setDateTime(now);
    
    // 初始化按钮状态
    ui->pauseSendButton->setEnabled(false);
    
    // 加载设置
    loadSettings();
}

MainWindow::~MainWindow()
{
    saveSettings();
    dataProcessor->stop();
    dataProcessor->wait();
    cleanupConnection();
    if (m_server) {
        m_server->close();
    }
    delete ui;
}

void MainWindow::initDatabase()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("chaomu_data.db");
    
    if (!db.open()) {
        qDebug() << "Error: Failed to connect database" << db.lastError().text();
        return;
    }
    
    QSqlQuery query;
    query.exec("CREATE TABLE IF NOT EXISTS ad_data ("
               "id INTEGER PRIMARY KEY AUTOINCREMENT,"
               "AD INTEGER,"
               "pos INTEGER,"
               "timestamp DATETIME DEFAULT CURRENT_TIMESTAMP"
               ")");
               
    if (query.lastError().isValid()) {
        qDebug() << "Error: Failed to create table" << query.lastError().text();
    }
}

void MainWindow::updateDisplay(int ad, int pos)
{
    ui->adLabel->setText(QString::number(ad));
    ui->posLabel->setText(QString::number(pos));
}

void MainWindow::updateCounter(int count)
{
    qDebug() << "Processed batch of" << count << "records";
}

void MainWindow::updateQueryCount(int count)
{
    queryCount = count;
    ui->queryCountLabel->setText(QString::fromLocal8Bit("查询到数据: %1").arg(count));
}

void MainWindow::updateSentCount(int count)
{
    sentCount = count;
    ui->sentCountLabel->setText(QString::fromLocal8Bit("已发送数据: %1").arg(count));
}

void MainWindow::updateNextData(const AdData &data)
{
    ui->nextDataLabel->setText(QString::fromLocal8Bit("发送数据: AD=%1, pos=%2")
                              .arg(data.ad)
                              .arg(data.pos));
}

void MainWindow::processReceivedData(int ad, int pos)
{
    AdData data;
    data.ad = ad;
    data.pos = pos;
    data.timestamp = QDateTime::currentDateTime();
    
    updateDisplay(ad, pos);
    
    dataCount++;
    ui->countLabel->setText(QString::number(dataCount));
    
    dataProcessor->addData(data);
    
    qDebug() << "Received data - AD:" << ad << "pos:" << pos;
}

void MainWindow::handleClientConnection(QLocalSocket *client)
{
    QDataStream in(client);
    in.setVersion(QDataStream::Qt_5_0);

    if (client->bytesAvailable() < (int)sizeof(quint32))
        return;

    quint32 blockSize = 0;
    in >> blockSize;

    if (client->bytesAvailable() < blockSize)
        return;

    int value1, value2;
    in >> value1 >> value2;
    
    processReceivedData(value1, value2);
}

void MainWindow::cleanupConnection()
{
    if (m_dataStream) {
        delete m_dataStream;
        m_dataStream = nullptr;
    }
    if (m_client) {
        m_client->disconnectFromServer();
        m_client = nullptr;
    }
    retryCount = 0;
}

void MainWindow::handleSocketError(QLocalSocket::LocalSocketError error)
{
    qDebug() << "Socket error:" << error;
    cleanupConnection();
    QMessageBox::warning(this, QString::fromLocal8Bit("连接错误"),
                        QString::fromLocal8Bit("连接发生错误，请重新连接"));
}

bool MainWindow::sendData(const AdData &data)
{
    if (!m_client || !m_dataStream || m_client->state() != QLocalSocket::ConnectedState) {
        return false;
    }

    QMutexLocker locker(&sendMutex);
    
    try {
        // 发送数据大小
        *m_dataStream << (quint32)(2 * sizeof(int));
        // 发送两个整数值
        *m_dataStream << data.ad << data.pos;
        
        // 等待数据发送完成
        if (!m_client->waitForBytesWritten(1000)) {
            qDebug() << "Failed to write data";
            return false;
        }
        
        qDebug() << "Sending data - AD:" << data.ad << "pos:" << data.pos;
        return true;
    } catch (...) {
        qDebug() << "Exception while sending data";
        return false;
    }
}

void MainWindow::sendSingleData()
{
    if (!sendQueue.isEmpty()) {
        AdData data = sendQueue.dequeue();
        updateNextData(data);  // 更新发送数据显示
        if (sendData(data)) {
            updateSentCount(sentCount + 1);
        } else {
            QMessageBox::warning(this, QString::fromLocal8Bit("发送错误"),
                               QString::fromLocal8Bit("发送数据失败，请检查连接"));
            sendQueue.prepend(data);  // 将数据放回队列
        }
    } else {
        QMessageBox::information(this, QString::fromLocal8Bit("发送完成"), 
                               QString::fromLocal8Bit("所有数据已发送完毕"));
    }
}

void MainWindow::sendNextData()
{
    if (!sendQueue.isEmpty()) {
        AdData data = sendQueue.dequeue();
        updateNextData(data);  // 更新发送数据显示
        if (sendData(data)) {
            updateSentCount(sentCount + 1);
            retryCount = 0;  // 重置重试计数
        } else {
            if (retryCount < MAX_RETRY_COUNT) {
                retryCount++;
                sendQueue.prepend(data);  // 将数据放回队列
                qDebug() << "Retry sending data, attempt" << retryCount;
            } else {
                sendTimer->stop();
                isSending = false;
                isPaused = false;
                ui->startSendButton->setText(QString::fromLocal8Bit("开始发送"));
                ui->pauseSendButton->setText(QString::fromLocal8Bit("暂停发送"));
                ui->pauseSendButton->setEnabled(false);
                ui->singleSendButton->setEnabled(true);
                QMessageBox::warning(this, QString::fromLocal8Bit("发送错误"),
                                   QString::fromLocal8Bit("发送数据失败，请检查连接"));
            }
        }
    } else {
        sendTimer->stop();
        isSending = false;
        isPaused = false;
        ui->startSendButton->setText(QString::fromLocal8Bit("开始发送"));
        ui->pauseSendButton->setText(QString::fromLocal8Bit("暂停发送"));
        ui->pauseSendButton->setEnabled(false);
        ui->singleSendButton->setEnabled(true);
        QMessageBox::information(this, QString::fromLocal8Bit("发送完成"), 
                               QString::fromLocal8Bit("所有数据已发送完毕"));
    }
}

void MainWindow::handleNewConnection()
{
    QLocalSocket *client = m_server->nextPendingConnection();
    if (client) {
        cleanupConnection();  // 清理现有连接
        
        m_client = client;
        m_dataStream = new QDataStream(m_client);
        m_dataStream->setVersion(QDataStream::Qt_5_0);
        
        connect(client, &QLocalSocket::readyRead, [this, client]() {
            handleClientConnection(client);
        });
        
        connect(client, &QLocalSocket::disconnected, [this]() {
            cleanupConnection();
        });
        
        connect(client, QOverload<QLocalSocket::LocalSocketError>::of(&QLocalSocket::error),
                this, &MainWindow::handleSocketError);
        
        connect(client, &QLocalSocket::disconnected, client, &QLocalSocket::deleteLater);
        
        qDebug() << "New client connected";
    }
}

void MainWindow::startServer()
{
    if (!serverRunning) {
        if (!m_server->listen("ChaoMuAdServer")) {
            QMessageBox::critical(this, QString::fromLocal8Bit("错误"), 
                                QString::fromLocal8Bit("无法启动服务器: %1").arg(m_server->errorString()));
            return;
        }
        
        connect(m_server, &QLocalServer::newConnection, this, &MainWindow::handleNewConnection);
        serverRunning = true;
        ui->pushButton->setText(QString::fromLocal8Bit("停止服务器"));
        QMessageBox::information(this, QString::fromLocal8Bit("服务器状态"), 
                               QString::fromLocal8Bit("服务器已启动，等待连接..."));
    } else {
        m_server->close();
        serverRunning = false;
        ui->pushButton->setText(QString::fromLocal8Bit("启动服务器"));
        QMessageBox::information(this, QString::fromLocal8Bit("服务器状态"), 
                               QString::fromLocal8Bit("服务器已停止"));
    }
}

void MainWindow::on_pushButton_clicked()
{
    startServer();
}

void MainWindow::on_startSendButton_clicked()
{
    if (!isSending) {
        queryAndSendData();
        isSending = true;
        isPaused = false;
        ui->startSendButton->setText(QString::fromLocal8Bit("停止发送"));
        ui->pauseSendButton->setEnabled(true);
        ui->singleSendButton->setEnabled(false);
        sendTimer->start(static_cast<int>(ui->frequencySpinBox->value() * 1000));
    } else {
        isSending = false;
        isPaused = false;
        ui->startSendButton->setText(QString::fromLocal8Bit("开始发送"));
        ui->pauseSendButton->setText(QString::fromLocal8Bit("暂停发送"));
        ui->pauseSendButton->setEnabled(false);
        ui->singleSendButton->setEnabled(true);
        sendTimer->stop();
    }
}

void MainWindow::on_pauseSendButton_clicked()
{
    if (!isPaused) {
        isPaused = true;
        sendTimer->stop();
        ui->pauseSendButton->setText(QString::fromLocal8Bit("继续发送"));
    } else {
        isPaused = false;
        sendTimer->start(static_cast<int>(ui->frequencySpinBox->value() * 1000));
        ui->pauseSendButton->setText(QString::fromLocal8Bit("暂停发送"));
    }
}

void MainWindow::on_singleSendButton_clicked()
{
    if (sendQueue.isEmpty()) {
        queryAndSendData();
    }
    sendSingleData();
}

void MainWindow::queryAndSendData()
{
    QDateTime startTime = ui->startTimeEdit->dateTime();
    QDateTime endTime = ui->endTimeEdit->dateTime();
    
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("chaomu_data.db");
    
    if (db.open()) {
        QSqlQuery query;
        query.prepare("SELECT AD, pos, timestamp FROM ad_data "
                     "WHERE timestamp BETWEEN ? AND ? "
                     "ORDER BY timestamp");
        query.addBindValue(startTime.toString("yyyy-MM-dd HH:mm:ss"));
        query.addBindValue(endTime.toString("yyyy-MM-dd HH:mm:ss"));
        
        if (query.exec()) {
            sendQueue.clear();
            int count = 0;
            while (query.next()) {
                AdData data;
                data.ad = query.value(0).toInt();
                data.pos = query.value(1).toInt();
                data.timestamp = query.value(2).toDateTime();
                sendQueue.enqueue(data);
                count++;
            }
            updateQueryCount(count);
            updateSentCount(0);
            qDebug() << "Found" << count << "records to send";
        } else {
            qDebug() << "Query error:" << query.lastError().text();
            QMessageBox::warning(this, QString::fromLocal8Bit("查询错误"),
                               QString::fromLocal8Bit("查询数据失败: %1").arg(query.lastError().text()));
        }
    }
}

void MainWindow::saveSettings()
{
    settings->setValue("startTime", ui->startTimeEdit->dateTime());
    settings->setValue("endTime", ui->endTimeEdit->dateTime());
    settings->setValue("frequency", ui->frequencySpinBox->value());
    settings->sync();
}

void MainWindow::loadSettings()
{
    ui->startTimeEdit->setDateTime(settings->value("startTime", QDateTime::currentDateTime().addDays(-1)).toDateTime());
    ui->endTimeEdit->setDateTime(settings->value("endTime", QDateTime::currentDateTime()).toDateTime());
    ui->frequencySpinBox->setValue(settings->value("frequency", 1.0).toDouble());
}

